//-----------------------------------------------------------------------------
// Name: collisiondetect.cpp
// Auth: PaulGodfrey
// Desc: methods and data for display
//-----------------------------------------------------------------------------

#include <windows.h>
#include "Display.h"

#include "Assert.h"
#include "DisplayManager.h"
#include "SharedConstants.h"
#include "Systems.h"
#include "AnimateObject.h"
#include "AnimateObjectManager.h"
#include "BulletManager.h"
#include "GunManager.h"
#include <iostream>
#include "Bounding.h"
#include <list>
#include "Bullet.h"
#include <math.h>
#include "CollisionDetect.h"
#include "InanimateObjectManager.h"
#include "InanimateObject.h"
#include "Display.h"

using namespace std;


//-----------------------------------------------------------------------------
//Runs collision checkers for area
void CheckCollisions(float elapsedTimeS, int area)
{
	cBulletManager* pBulletManager = GetBulletManager();
	cAnimateObjectManager* pAnimateObjectManager = GetAnimateObjectManager();
	list<cBullet>* liBullets = pBulletManager->GetBulletList();

	cInanimateObjectManager* pInanimateObjectManager = GetInanimateObjectManager();
	list<cInanimateObject>* liInanimate = pInanimateObjectManager->GetInanimateList();

	int numcheck[3];
	bool empty=true;
	if(area!=-1 && area!=24 && area!=25 && area!=-2 && area!=-100 && area!=-99)
	{
		if(area==0)
		{
			numcheck[0]=0;
			numcheck[1]=1;
			numcheck[2]=22;
		}
		else if(area==22)
		{
			numcheck[0]=22;
			numcheck[1]=0;
			numcheck[2]=21;
		}
		else
		{
			numcheck[0]=area;
			numcheck[1]=area+1;
			numcheck[2]=area-1;
		}
		for(int i=0; i<3; i++)
		{
			list<cAnimateObject>* liAnimate=&pAnimateObjectManager->vAnimateLists[numcheck[i]];

			if(!liAnimate->empty())
			{		
				empty=false;
			}
		}
		if (empty==false)
		{
			CheckBulletvsAnimate(area);
			CheckAnimatevsAnimate(elapsedTimeS, area);
		}
	}
	if(!(liBullets->empty()) && !(liInanimate->empty()))
	{
		CheckBulletvsInanimate();
	}


}

//Runs boss collision checkers when boss is active
void CheckBossCollisions(float elapsedTimeS)
{
	//TODO: Fix for vectors
	cBulletManager* pBulletManager = GetBulletManager();
	cAnimateObjectManager* pAnimateObjectManager = GetAnimateObjectManager();
	list<cBullet>* liBullets = pBulletManager->GetBulletList();
	list<cAnimateObject>* liAnimate = pAnimateObjectManager->GetBossList();
	cInanimateObjectManager* pInanimateObjectManager = GetInanimateObjectManager();
	list<cInanimateObject>* liInanimate = pInanimateObjectManager->GetInanimateList();

	if(!(liBullets->empty()) && !(liAnimate->empty()))
	{
		CheckBossBulletvsAnimate();
	}
	if(!(liAnimate->empty()) && !(liAnimate->size()==1))
	{
		CheckBossAnimatevsAnimate(elapsedTimeS);
	}
	if(!(liBullets->empty()) && !(liInanimate->empty()))
	{
		CheckBulletvsInanimate();
	}


}

//Checks bullets vs animate objects
void CheckBulletvsAnimate(int area)
{
	cDisplayManager* pDisplayManager = GetDisplayManager();
	cBulletManager* pBulletManager = GetBulletManager();
	cAnimateObjectManager* pAnimateObjectManager = GetAnimateObjectManager();
	int numcheck[3];
	if(area==0)
	{
		numcheck[0]=0;
		numcheck[1]=1;
		numcheck[2]=22;
	}
	else if(area==22)
	{
		numcheck[0]=22;
		numcheck[1]=0;
		numcheck[2]=21;
	}
	else
	{
		numcheck[0]=area;
		numcheck[1]=area+1;
		numcheck[2]=area-1;
	}
	for(int i=0; i<3; i++)
	{
		list<cAnimateObject>* liAnimate=&pAnimateObjectManager->vAnimateLists[numcheck[i]];

	
		list<cBullet>* liBullets = pBulletManager->GetBulletList();
		list<cBullet>::iterator itBul;
		
		itBul=liBullets->begin();
		for(itBul; itBul!=liBullets->end();)
		{
			bool Body = false;
			bool Head = false;
			//if(itBul->GetDist()>0.5f)
			{
				cBullet *bul = &*itBul;
				cBounding* bBounding=bul->GetBounding();
	
				list<cAnimateObject>::iterator itAO;

				itAO = liAnimate->begin();
				
				for(itAO; itAO!=liAnimate->end();)
				{
					cBounding* dBoundingH = itAO->GetBoundingHead();
					vector<cBounding>* dBoundingB = itAO->GetBoundingBody();
					cBounding* dBoundingM = itAO->GetBoundingMaster();
	
					float masterRad = dBoundingM->GetSphereRadius()+bBounding->GetSphereRadius();
					float a1X = dBoundingM->GetSphereX();
					float a1Y = dBoundingM->GetSphereY();
					float a1Z = dBoundingM->GetSphereZ();
					float a2X = bBounding->GetSphereX();
					float a2Y = bBounding->GetSphereY();
					float a2Z = bBounding->GetSphereZ();
					float distance = sqrt(((a2X-a1X)*(a2X-a1X))+((a2Y-a1Y)*(a2Y-a1Y))+((a2Z-a1Z)*(a2Z-a1Z)));

					//If bullet is inside the master sphere
					if(distance<masterRad)
					{
	
						float rHeadCombo = bBounding->GetSphereRadius()+ dBoundingH->GetSphereRadius();
	
						float rHeadDist = sqrt(((bBounding->GetSphereX()-dBoundingH->GetSphereX())*(bBounding->GetSphereX()-dBoundingH->GetSphereX()))+((bBounding->GetSphereY()-dBoundingH->GetSphereY())*(bBounding->GetSphereY()-dBoundingH->GetSphereY()))+((bBounding->GetSphereZ()-dBoundingH->GetSphereZ())*(bBounding->GetSphereZ()-dBoundingH->GetSphereZ())));
					
						//Check for head shot
						if(rHeadCombo>rHeadDist)
						{
							Head=true;
						}
						//Check for body shot if no headshot
						if(!Head)
						{
							for(int i=0; i<(int)dBoundingB->size(); i++)
							{
								float rBodyCombo = bBounding->GetSphereRadius()+dBoundingB->at(i).GetSphereRadius();
	
								float rBodyDist = sqrt(((bBounding->GetSphereX()-dBoundingB->at(i).GetSphereX())*(bBounding->GetSphereX()-dBoundingB->at(i).GetSphereX()))+((bBounding->GetSphereY()-dBoundingB->at(i).GetSphereY())*(bBounding->GetSphereY()-dBoundingB->at(i).GetSphereY()))+((bBounding->GetSphereZ()-dBoundingB->at(i).GetSphereZ())*(bBounding->GetSphereZ()-dBoundingB->at(i).GetSphereZ())));
								
								if(rBodyCombo>rBodyDist)
								{
									Body=true;
								}
							}
						}
					}
					//If body shot
					if(Body)
					{
						//If non-zombie - reduce health or vaccinate, depending on bullet
						if(itAO->GetType()==kHuman || itAO->GetType()==kCow)
						{
							if(itBul->GetLifeSpan()==kVacDist && itAO->GetType()==kHuman )
							{
								itAO->SetType(kHumanVaccinated);
								pDisplayManager->SetPoints(pDisplayManager->GetPoints()+10);
								pDisplayManager->SetDead(2);
							}
							else if (itBul->GetLifeSpan()==kVacDist && itAO->GetType()==kCow )
							{
								itAO->SetType(kCowVaccinated);
								pDisplayManager->SetPoints(pDisplayManager->GetPoints()+10);
								pDisplayManager->SetDead(2);
							}
							else if(itAO->GetType()!=kZombie && itAO->GetType()!=kCowZombie)
							{
								itAO->UpdateHealth(-(itBul->GetDamage()));
							}
	
							
						}
						itBul->SetStatus(false);
						Body=false;
					}
					//If head shot - DIE and kill bullet
					if(Head)
					{
						itAO->SetHealth(0);
						itBul->SetStatus(false);
						Head=false;
					}
					if(itAO!=liAnimate->end())
					{
						itAO++;
					}
				}
		
			}
			if(itBul!=liBullets->end())
			{
				itBul++;
			}		
		
		}
	}
}

//Checks bullets vs animates in boss area
void CheckBossBulletvsAnimate()
{
	cDisplayManager* pDisplayManager = GetDisplayManager();
	cBulletManager* pBulletManager = GetBulletManager();
	cAnimateObjectManager* pAnimateObjectManager = GetAnimateObjectManager();

	list<cAnimateObject>* liAnimate=pAnimateObjectManager->GetBossList();

	
	list<cBullet>* liBullets = pBulletManager->GetBulletList();
	list<cBullet>::iterator itBul;
	
	itBul=liBullets->begin();
	for(itBul; itBul!=liBullets->end();)
	{
		bool Body = false;
		bool Head = false;
		//if(itBul->GetDist()>0.5f)
		{
			cBullet *bul = &*itBul;
			cBounding* bBounding=bul->GetBounding();

			list<cAnimateObject>::iterator itAO;

			itAO = liAnimate->begin();
			
			for(itAO; itAO!=liAnimate->end();)
			{
				cBounding* dBoundingH = itAO->GetBoundingHead();
				vector<cBounding>* dBoundingB = itAO->GetBoundingBody();
				cBounding* dBoundingM = itAO->GetBoundingMaster();

				float masterRad = dBoundingM->GetSphereRadius()+bBounding->GetSphereRadius();
				float a1X = dBoundingM->GetSphereX();
				float a1Y = dBoundingM->GetSphereY();
				float a1Z = dBoundingM->GetSphereZ();
				float a2X = bBounding->GetSphereX();
				float a2Y = bBounding->GetSphereY();
				float a2Z = bBounding->GetSphereZ();
				float distance = sqrt(((a2X-a1X)*(a2X-a1X))+((a2Y-a1Y)*(a2Y-a1Y))+((a2Z-a1Z)*(a2Z-a1Z)));
				//If it's inside master sphere and not the boss
				if(distance<masterRad && itAO->GetType()!=kBoss)
				{

					float rHeadCombo = bBounding->GetSphereRadius()+ dBoundingH->GetSphereRadius();

					float rHeadDist = sqrt(((bBounding->GetSphereX()-dBoundingH->GetSphereX())*(bBounding->GetSphereX()-dBoundingH->GetSphereX()))+((bBounding->GetSphereY()-dBoundingH->GetSphereY())*(bBounding->GetSphereY()-dBoundingH->GetSphereY()))+((bBounding->GetSphereZ()-dBoundingH->GetSphereZ())*(bBounding->GetSphereZ()-dBoundingH->GetSphereZ())));
					//Head shot check
					if(rHeadCombo>rHeadDist)
					{
						Head=true;
					}
					if(!Head)
					{
						for(int i=0; i<(int)dBoundingB->size(); i++)
						{
							float rBodyCombo = bBounding->GetSphereRadius()+dBoundingB->at(i).GetSphereRadius();

							float rBodyDist = sqrt(((bBounding->GetSphereX()-dBoundingB->at(i).GetSphereX())*(bBounding->GetSphereX()-dBoundingB->at(i).GetSphereX()))+((bBounding->GetSphereY()-dBoundingB->at(i).GetSphereY())*(bBounding->GetSphereY()-dBoundingB->at(i).GetSphereY()))+((bBounding->GetSphereZ()-dBoundingB->at(i).GetSphereZ())*(bBounding->GetSphereZ()-dBoundingB->at(i).GetSphereZ())));
							
							if(rBodyCombo>rBodyDist)
							{
								Body=true;
							}
						}
					}
					//Kill on headshot
					if(Head)
					{
						itAO->SetHealth(0);
						itBul->SetStatus(false);
						Head=false;
					}
				}
				//Else if it is the boss and inside the master sphere
				else if(distance<masterRad)
				{
					//Check against all heads
					for(int i=0; i<(int)dBoundingB->size(); i++)
					{
						float rBodyCombo = bBounding->GetSphereRadius()+dBoundingB->at(i).GetSphereRadius();

						float rBodyDist = sqrt(((bBounding->GetSphereX()-dBoundingB->at(i).GetSphereX())*(bBounding->GetSphereX()-dBoundingB->at(i).GetSphereX()))+((bBounding->GetSphereY()-dBoundingB->at(i).GetSphereY())*(bBounding->GetSphereY()-dBoundingB->at(i).GetSphereY()))+((bBounding->GetSphereZ()-dBoundingB->at(i).GetSphereZ())*(bBounding->GetSphereZ()-dBoundingB->at(i).GetSphereZ())));
						
						//Set the relevent head to false
						if(rBodyCombo>rBodyDist)
						{
							itAO->SetBossHeadStatus(i);
							Body=true;
						}
					}
				}
				if(itAO!=liAnimate->end())
				{
					itAO++;
				}
			}
	
		}
		if(itBul!=liBullets->end())
		{
			itBul++;
		}		
	
	}
	
}

//Check bullets vs inanimate objects
void CheckBulletvsInanimate()
{
	cBulletManager* pBulletManager = GetBulletManager();
	cInanimateObjectManager* pInanimateObjectManager = GetInanimateObjectManager();
	bool Hit = false;

	
	list<cInanimateObject>* liInanimate = pInanimateObjectManager->GetInanimateList();
	list<cInanimateObject>::iterator itIAO;

	list<cBullet>* liBullets = pBulletManager->GetBulletList();
	list<cBullet>::iterator itBul;
	
	itBul=liBullets->begin();
	for(itBul; itBul!=liBullets->end();)
	{
//		if(itBul->GetDist()>0.5f)
		{
			cBullet *bul = &*itBul;
			cBounding* bBounding=bul->GetBounding();


			itIAO = liInanimate->begin();
			
			for(itIAO; itIAO!=liInanimate->end();)
			{
				cBounding* dBounding = itIAO->GetBounding();
					
				for(itIAO; itIAO!=liInanimate->end();)
				{
					cBounding *aBounding = (&*itIAO)->GetBounding();

					float minX = aBounding->getMinX();
					float maxX = aBounding->getMaxX();
					float minY = aBounding->getMinY();
					float maxY = aBounding->getMaxY();
					float minZ = aBounding->getMinZ();
					float maxZ = aBounding->getMaxZ();

			
					float inanimateX = itIAO->GetPositionX();
					float inanimateY = itIAO->GetPositionY();
					float inanimateZ = itIAO->GetPositionZ();

					float vectorX = bul->GetPositionX() - inanimateX;
					float vectorY = bul->GetPositionY() - inanimateY;
					float vectorZ = bul->GetPositionZ() - inanimateZ;

					float vLen = sqrt((vectorX*vectorX)+(vectorY*vectorY)+(vectorZ*vectorZ));

					float percentage = bBounding->GetSphereRadius()/vLen;

					float testX = vectorX*percentage;
					float testY = vectorY*percentage;
					float testZ = vectorZ*percentage;
					
					if(((bul->GetPositionX()+testX>minX) && (bul->GetPositionX()+testX<maxX)) && ((bul->GetPositionY()+testY>minY) && (bul->GetPositionY()+testY<maxY)) && ((bul->GetPositionZ()+testZ>minZ) && (bul->GetPositionZ()+testZ<maxZ)))
					{
						Hit = true;
					}

					//If a bullet hits an inanimate object - kill it
					if(Hit)
					{
						itBul->SetStatus(false);
					}

					if(itIAO!=liInanimate->end())
					{
						itIAO++;
					}
				}
			}
			
			if(itBul!=liBullets->end())
			{
				itBul++;
			}
		}
	}

}

//Check collisions of animates vs animates 
void CheckAnimatevsAnimate(float elapsedTimeS, int area)
{
	int nonDamageCounter = 0;
	cDisplayManager* pDisplayManager = GetDisplayManager();
	cAnimateObjectManager* pAnimateObjectManager = GetAnimateObjectManager();
	bool playCollision = false;
	bool animCollision = false;

	
	//list<cAnimateObject>* liAnimate = pAnimateObjectManager->GetAnimateList();
	list<cAnimateObject>* liAnimate=&pAnimateObjectManager->vAnimateLists[area];
	list<cAnimateObject>::iterator itAO;
	list<cAnimateObject>::iterator itAO2;
	list<cAnimateObject>::iterator itAOTemp;

    vector<cBounding>* dBounding = pDisplayManager->GetBoundingBody();
	cBounding* dBoundingMaster = pDisplayManager->GetBoundingMaster();
	if(!liAnimate->empty())
	{
	itAO = liAnimate->begin();
	itAO2 = liAnimate->begin();
	itAOTemp = itAO2;
	for(itAO; itAO!=liAnimate->end();)
	{
		//nonDamageCounter=0;
		vector<cBounding>* a1Bounding = itAO->GetBoundingBody();
		cBounding* a1Master = itAO->GetBoundingMaster();
	    if(itAOTemp!=liAnimate->end())
		{
		itAOTemp++;
		itAO2=itAOTemp;
		for(itAO2; itAO2!=liAnimate->end();)
		{
			vector<cBounding>* a2Bounding = itAO2->GetBoundingBody();
			cBounding* a2Master = itAO2->GetBoundingMaster();

			float masterRad = a1Master->GetSphereRadius()+a2Master->GetSphereRadius();
			float a1X = a1Master->GetSphereX();
			float a1Z = a1Master->GetSphereZ();
			float a2X = a2Master->GetSphereX();
			float a2Z = a2Master->GetSphereZ();
			float distance = sqrt(((a2X-a1X)*(a2X-a1X))+((a2Z-a1Z)*(a2Z-a1Z)));
			if(distance<masterRad)
			{
				for(int i=0; i < (int)a1Bounding->size(); i++)
				{
					float a1Rad = a1Bounding->at(i).GetSphereRadius();
					float a1X = a1Bounding->at(i).GetSphereX();
					float a1Z = a1Bounding->at(i).GetSphereZ();

					for(int j=0; j < (int) a2Bounding->size(); j++)
					{
						float a2Rad = a2Bounding->at(j).GetSphereRadius();
						float a2X = a2Bounding->at(j).GetSphereX();
						float a2Z = a2Bounding->at(j).GetSphereZ();

						float radTotal = a1Rad + a2Rad;

						float rBodyDist = sqrt(((a1X-a2X)*(a1X-a2X))+((a1Z-a2Z)*(a1Z-a2Z))); 

						if(radTotal>rBodyDist)
						{
							animCollision=true;
						}
						
					}

				}
			}
			//If there is a collision
			if(animCollision)
			{
				static int plus=-1;
				float speed1 = itAO->GetSpeed();
				float speed2 = itAO2->GetSpeed();

				float xFDirection = cos((itAO->GetYaw())*kDegreesToRadians);
				float zFDirection = sin((itAO->GetYaw())*kDegreesToRadians);
				itAO->SetPosition(itAO->GetPositionX()-((speed1*20 * elapsedTimeS) * xFDirection), itAO->GetPositionY(), itAO->GetPositionZ()-((speed1*20 * elapsedTimeS) * zFDirection));
				
				xFDirection = cos((itAO2->GetYaw())*kDegreesToRadians);
				zFDirection = sin((itAO2->GetYaw())*kDegreesToRadians);
				itAO2->SetYaw(itAO2->GetYaw()+(120.0f*plus));
				itAO2->SetPosition(itAO2->GetPositionX()+((speed1*20 * elapsedTimeS) * xFDirection), itAO2->GetPositionY(), itAO2->GetPositionZ()+((speed1*20 * elapsedTimeS) * zFDirection));

				//Cause infections!
				if((itAO->GetType()==kZombie && itAO2->GetType()==kHuman))
				{
					itAO2->SetType(kZombie);
				}
				if((itAO->GetType()==kHuman && itAO2->GetType()==kZombie))
				{
					itAO->SetType(kZombie);
				}
				if((itAO->GetType()==kZombie && itAO2->GetType()==kCow))
				{
					itAO2->SetType(kCowZombie);
				}
				if((itAO->GetType()==kCow && itAO2->GetType()==kZombie))
				{
					itAO->SetType(kCowZombie);
				}
				if((itAO->GetType()==kCowZombie && itAO2->GetType()==kHuman))
				{
					itAO2->SetType(kZombie);
				}
				if((itAO->GetType()==kHuman && itAO2->GetType()==kCowZombie))
				{
					itAO->SetType(kZombie);
				}
				if((itAO->GetType()==kCowZombie && itAO2->GetType()==kCow))
				{
					itAO2->SetType(kCowZombie);
				}
				if((itAO->GetType()==kCow && itAO2->GetType()==kCowZombie))
				{
					itAO->SetType(kCowZombie);
				}
				xFDirection = cos((itAO2->GetYaw())*kDegreesToRadians);
				zFDirection = sin((itAO2->GetYaw())*kDegreesToRadians);
				itAO2->SetPosition(itAO2->GetPositionX()-((speed2*20 * elapsedTimeS) * xFDirection), itAO2->GetPositionY(), itAO2->GetPositionZ()-((speed2*20 * elapsedTimeS) * zFDirection));
				
				xFDirection = cos((itAO->GetYaw())*kDegreesToRadians);
				zFDirection = sin((itAO->GetYaw())*kDegreesToRadians);
				itAO->SetYaw(itAO->GetYaw()+(120.0f*plus));
				itAO->SetPosition(itAO->GetPositionX()+((speed2*20 * elapsedTimeS) * xFDirection), itAO->GetPositionY(), itAO->GetPositionZ()+((speed2*20 * elapsedTimeS) * zFDirection));

				plus*=-1;
				animCollision=false;
			}


			if(itAO2!=liAnimate->end())
			{
				itAO2++;
			}
			}
		}

		float masterRad = a1Master->GetSphereRadius()+dBoundingMaster->GetSphereRadius();
		float a1X = a1Master->GetSphereX();
		float a1Z = a1Master->GetSphereZ();
		float a2X = dBoundingMaster->GetSphereX();
		float a2Z = dBoundingMaster->GetSphereZ();
		float distance = sqrt(((a2X-a1X)*(a2X-a1X))+((a2Z-a1Z)*(a2Z-a1Z)));
		//Check against player
		if(distance<masterRad)
		{
			for(int i=0; i < (int)a1Bounding->size(); i++)
			{
				float a1Rad = a1Bounding->at(i).GetSphereRadius();
				float a1X = a1Bounding->at(i).GetSphereX();
				float a1Z = a1Bounding->at(i).GetSphereZ();

				for(int j=0; j < (int)dBounding->size(); j++)
				{
					float dRad = dBounding->at(j).GetSphereRadius();
					float dX = dBounding->at(j).GetSphereX();
					float dZ = dBounding->at(j).GetSphereZ();

					float radTotal = a1Rad + dRad;

					float rBodyDist = sqrt(((a1X-dX)*(a1X-dX))+((a1Z-dZ)*(a1Z-dZ))); 

					if(radTotal>rBodyDist && kplayCollisions)
					{
						playCollision=true;
					}
					
				}

			}
		}

		//If theres a player collision
		if(playCollision)
		{
			float speed1 = itAO->GetSpeed();
			float xFDirection = cos((itAO->GetYaw())*kDegreesToRadians);
			float zFDirection = sin((itAO->GetYaw())*kDegreesToRadians);
			itAO->SetPosition(itAO->GetPositionX()-((speed1*5 * elapsedTimeS) * xFDirection), itAO->GetPositionY(), itAO->GetPositionZ()-((speed1*5 * elapsedTimeS) * zFDirection));
			float yawDiff = pDisplayManager->GetCameraHeading()-itAO->GetYaw();
			if (yawDiff<0.0f)
			{
				yawDiff+=360.0f;
			}
			if(yawDiff>360.0f)
			{
				yawDiff-=360.0f;
			}
			//Set damage directions for HUD
			if(yawDiff>315.0f || yawDiff<45.0f)
			{
				pDisplayManager->SetDamageDirection(kDamageBack);
			}
			else if(yawDiff>225.0f && yawDiff<315.0f)
			{
				pDisplayManager->SetDamageDirection(kDamageRight);
			}
			else if(yawDiff<135.0f && yawDiff>45.0f)
			{
				pDisplayManager->SetDamageDirection(kDamageLeft);
			}
			//REduce health on contact with zombies
			if(itAO->GetType()==kZombie || itAO->GetType()==kCowZombie)
			{
				pDisplayManager->SetHealth(pDisplayManager->GetHealth()-1);
			}
			
			float fSpeed = pDisplayManager->GetFSpeed();
			float sSpeed = pDisplayManager->GetSSpeed();

			xFDirection = cos((pDisplayManager->GetCameraHeading()-90)*kDegreesToRadians);
			zFDirection = cos((pDisplayManager->GetCameraHeading())*kDegreesToRadians);

			float xSDirection = sin((pDisplayManager->GetCameraHeading()-90)*kDegreesToRadians);
			float zSDirection = sin((pDisplayManager->GetCameraHeading())*kDegreesToRadians);

			pDisplayManager->SetCameraX(pDisplayManager->GetCameraX()-(((fSpeed*5 * elapsedTimeS) * xFDirection)+((sSpeed*5 * elapsedTimeS) * xSDirection)));
			pDisplayManager->SetCameraZ(pDisplayManager->GetCameraZ()-(((fSpeed*5 * elapsedTimeS) * zFDirection)+((sSpeed*5 * elapsedTimeS) * zSDirection)));

		}
		else
		{
			nonDamageCounter+=1;
			if(nonDamageCounter==liAnimate->size())
			{
				pDisplayManager->SetDamageDirection(0);
			}
			
		}

		if(itAO!=liAnimate->end())
		{
			itAO++;
		}

		}
	}

}

//Check animate vs animates in boss list
void CheckBossAnimatevsAnimate(float elapsedTimeS)
{
	int nonDamageCounter = 0;
	cDisplayManager* pDisplayManager = GetDisplayManager();
	cAnimateObjectManager* pAnimateObjectManager = GetAnimateObjectManager();
	bool playCollision = false;
	bool animCollision = false;

	list<cAnimateObject>* liAnimate=pAnimateObjectManager->GetBossList();
	list<cAnimateObject>::iterator itAO;
	list<cAnimateObject>::iterator itAO2;
	list<cAnimateObject>::iterator itAOTemp;

    vector<cBounding>* dBounding = pDisplayManager->GetBoundingBody();
	cBounding* dBoundingMaster = pDisplayManager->GetBoundingMaster();

	itAO = liAnimate->begin();
	itAO2 = liAnimate->begin();
	itAOTemp = itAO2;
	for(itAO; itAO!=liAnimate->end();)
	{
		//nonDamageCounter=0;
		vector<cBounding>* a1Bounding = itAO->GetBoundingBody();
		cBounding* a1Master = itAO->GetBoundingMaster();
	    if(itAOTemp!=liAnimate->end())
		{
		itAOTemp++;
		itAO2=itAOTemp;
		for(itAO2; itAO2!=liAnimate->end();)
		{
			vector<cBounding>* a2Bounding = itAO2->GetBoundingBody();
			cBounding* a2Master = itAO2->GetBoundingMaster();

			float masterRad = a1Master->GetSphereRadius()+a2Master->GetSphereRadius();
			float a1X = a1Master->GetSphereX();
			float a1Z = a1Master->GetSphereZ();
			float a2X = a2Master->GetSphereX();
			float a2Z = a2Master->GetSphereZ();
			float distance = sqrt(((a2X-a1X)*(a2X-a1X))+((a2Z-a1Z)*(a2Z-a1Z)));

			if(distance<masterRad)
			{
				for(int i=0; i < (int)a1Bounding->size(); i++)
				{
					float a1Rad = a1Bounding->at(i).GetSphereRadius();
					float a1X = a1Bounding->at(i).GetSphereX();
					float a1Z = a1Bounding->at(i).GetSphereZ();

					for(int j=0; j < (int) a2Bounding->size(); j++)
					{
						float a2Rad = a2Bounding->at(j).GetSphereRadius();
						float a2X = a2Bounding->at(j).GetSphereX();
						float a2Z = a2Bounding->at(j).GetSphereZ();

						float radTotal = a1Rad + a2Rad;

						float rBodyDist = sqrt(((a1X-a2X)*(a1X-a2X))+((a1Z-a2Z)*(a1Z-a2Z))); 

						if(radTotal>rBodyDist)
						{
							animCollision=true;
						}
						
					}

				}
			}
			
			if(animCollision)
			{
				static int plus=-1;
				float speed1 = itAO->GetSpeed();
				float speed2 = itAO2->GetSpeed();

				float xFDirection = cos((itAO->GetYaw())*kDegreesToRadians);
				float zFDirection = sin((itAO->GetYaw())*kDegreesToRadians);
				itAO->SetPosition(itAO->GetPositionX()-((speed1*20 * elapsedTimeS) * xFDirection), itAO->GetPositionY(), itAO->GetPositionZ()-((speed1*20 * elapsedTimeS) * zFDirection));
				
				xFDirection = cos((itAO2->GetYaw())*kDegreesToRadians);
				zFDirection = sin((itAO2->GetYaw())*kDegreesToRadians);
				itAO2->SetYaw(itAO2->GetYaw()+(120.0f*plus));
				itAO2->SetPosition(itAO2->GetPositionX()+((speed1*20 * elapsedTimeS) * xFDirection), itAO2->GetPositionY(), itAO2->GetPositionZ()+((speed1*20 * elapsedTimeS) * zFDirection));


				xFDirection = cos((itAO2->GetYaw())*kDegreesToRadians);
				zFDirection = sin((itAO2->GetYaw())*kDegreesToRadians);
				itAO2->SetPosition(itAO2->GetPositionX()-((speed2*20 * elapsedTimeS) * xFDirection), itAO2->GetPositionY(), itAO2->GetPositionZ()-((speed2*20 * elapsedTimeS) * zFDirection));
				
				xFDirection = cos((itAO->GetYaw())*kDegreesToRadians);
				zFDirection = sin((itAO->GetYaw())*kDegreesToRadians);
				itAO->SetYaw(itAO->GetYaw()+(120.0f*plus));
				itAO->SetPosition(itAO->GetPositionX()+((speed2*20 * elapsedTimeS) * xFDirection), itAO->GetPositionY(), itAO->GetPositionZ()+((speed2*20 * elapsedTimeS) * zFDirection));

				plus*=-1;
				animCollision=false;
			}


			if(itAO2!=liAnimate->end())
			{
				itAO2++;
			}
			}
		}

		float masterRad = a1Master->GetSphereRadius()+dBoundingMaster->GetSphereRadius();
		float a1X = a1Master->GetSphereX();
		float a1Z = a1Master->GetSphereZ();
		float a2X = dBoundingMaster->GetSphereX();
		float a2Z = dBoundingMaster->GetSphereZ();
		float distance = sqrt(((a2X-a1X)*(a2X-a1X))+((a2Z-a1Z)*(a2Z-a1Z)));
		if(distance<masterRad)
		{
			for(int i=0; i < (int)a1Bounding->size(); i++)
			{
				float a1Rad = a1Bounding->at(i).GetSphereRadius();
				float a1X = a1Bounding->at(i).GetSphereX();
				float a1Z = a1Bounding->at(i).GetSphereZ();

				for(int j=0; j < (int)dBounding->size(); j++)
				{
					float dRad = dBounding->at(j).GetSphereRadius();
					float dX = dBounding->at(j).GetSphereX();
					float dZ = dBounding->at(j).GetSphereZ();

					float radTotal = a1Rad + dRad;

					float rBodyDist = sqrt(((a1X-dX)*(a1X-dX))+((a1Z-dZ)*(a1Z-dZ))); 

					if(radTotal>rBodyDist && kplayCollisions)
					{
						playCollision=true;
					}
					
				}

			}
		}

		if(playCollision)
		{
			float speed1 = itAO->GetSpeed();
			float xFDirection = cos((itAO->GetYaw())*kDegreesToRadians);
			float zFDirection = sin((itAO->GetYaw())*kDegreesToRadians);
			itAO->SetPosition(itAO->GetPositionX()-((speed1*5 * elapsedTimeS) * xFDirection), itAO->GetPositionY(), itAO->GetPositionZ()-((speed1*5 * elapsedTimeS) * zFDirection));
			float yawDiff = pDisplayManager->GetCameraHeading()-itAO->GetYaw();
			if (yawDiff<0.0f)
			{
				yawDiff+=360.0f;
			}
			if(yawDiff>360.0f)
			{
				yawDiff-=360.0f;
			}
			if(yawDiff>315.0f || yawDiff<45.0f)
			{
				pDisplayManager->SetDamageDirection(kDamageBack);
			}
			else if(yawDiff>225.0f && yawDiff<315.0f)
			{
				pDisplayManager->SetDamageDirection(kDamageRight);
			}
			else if(yawDiff<135.0f && yawDiff>45.0f)
			{
				pDisplayManager->SetDamageDirection(kDamageLeft);
			}
			if(itAO->GetType()==kZombie || itAO->GetType()==kCowZombie || itAO->GetType()==kBoss)
			{
				pDisplayManager->SetHealth(pDisplayManager->GetHealth()-1);
			}
			
			float fSpeed = pDisplayManager->GetFSpeed();
			float sSpeed = pDisplayManager->GetSSpeed();

			xFDirection = cos((pDisplayManager->GetCameraHeading()-90)*kDegreesToRadians);
			zFDirection = cos((pDisplayManager->GetCameraHeading())*kDegreesToRadians);

			float xSDirection = sin((pDisplayManager->GetCameraHeading()-90)*kDegreesToRadians);
			float zSDirection = sin((pDisplayManager->GetCameraHeading())*kDegreesToRadians);

			pDisplayManager->SetCameraX(pDisplayManager->GetCameraX()-(((fSpeed*5 * elapsedTimeS) * xFDirection)+((sSpeed*5 * elapsedTimeS) * xSDirection)));
			pDisplayManager->SetCameraZ(pDisplayManager->GetCameraZ()-(((fSpeed*5 * elapsedTimeS) * zFDirection)+((sSpeed*5 * elapsedTimeS) * zSDirection)));

		}
		else
		{
			nonDamageCounter+=1;
			if(nonDamageCounter==liAnimate->size())
			{
				pDisplayManager->SetDamageDirection(0);
			}
			
		}

		if(itAO!=liAnimate->end())
		{
			itAO++;
		}

	}

}


//Return the area for an object that asks for it
int CheckArea(float x,float z)
{
	int area = 0;

	//Check Area1
	if((x>-85&&x<15)&&(z>-150 && z<-120))
	{
		area=1;
	}

	//Check Area2
	else if((x>-115&&x<-85)&&(z>-150 && z<-70))
	{
		area=2;
	}

	//Check Area3
	else if((x>-215&&x<-115)&&(z>-100 && z<-70))
	{
		area=3;
	}

	//Check Area4
	else if((x>-215&&x<-180)&&(z>-70 && z<0))
	{
		area=4;
	}

	//Check Area5
	else if((x>-215&&x<-180)&&(z>0 && z<80))
	{
		area=5;
	}

	//Check Area6
	else if((x>-180&&x<-130)&&(z>50 && z<80))
	{
		area=6;
	}

	//Check Area7
	else if((x>-160&&x<-130)&&(z>80 && z<130))
	{
		area=7;
	}

	//Check Area8
	else if((x>-170&&x<-70)&&(z>130 && z<230))
	{
		area=8;
	}

	//Check Area9
	else if((x>-70&&x<-30)&&(z>180 && z<210))
	{
		area=9;
	}

	//Check Area10
	else if((x>-30&&x<40)&&(z>180 && z<210))
	{
		area=10;
	}

	//Check Area11
	else if((x>40&&x<100)&&(z>180 && z<210))
	{
		area=11;
	}

	//Check Area12
	else if((x>100&&x<130)&&(z>130 && z<210))
	{
		area=12;
	}

	//Check Area13
	else if((x>130&&x<170)&&(z>130 && z<160))
	{
		area=13;
	}

	//Check Area14
	else if((x>170&&x<200)&&(z>90 && z<160))
	{
		area=14;
	}

	//Check Area15
	else if((x>130&&x<170)&&(z>90 && z<120))
	{
		area=15;
	}

	//Check Area16
	else if((x>130&&x<160)&&(z>50 && z<90))
	{
		area=16;
	}

	//Check Area17
	else if((x>110&&x<210)&&(z>-50 && z<50))
	{
		area=17;
	}

	//Check Area18
	else if((x>175&&x<205)&&(z>-80 && z<-50))
	{
		area=18;
	}

	//Check Area19
	else if((x>175&&x<205)&&(z>-170 && z<-80))
	{
		area=19;
	}

	//Check Area20
	else if((x>175&&x<205)&&(z>-200 && z<-170))
	{
		area=20;
	}

	//Check Area21
	else if((x>115&&x<175)&&(z>-200 && z<-170))
	{
		area=21;
	}

	//Check Area22
	else if((x>115&&x<145)&&(z>-170 && z<-120))
	{
		area=22;
	}

	//Check Area23
	else if((x>15&&x<115)&&(z>-150 && z<-120))
	{
		area=23;
	}

	//Check Area24
	else if((x>10&&x<40)&&(z>120 && z<180))
	{
		area=24;
	}

	//Check Area25
	else if((x>-20&&x<10)&&(z>100 && z<150))
	{
		area=25;
	}
	//Check safe zone
	else if((x>-15&&x<15)&&(z>-180 && z<-150))
	{
		area=-1;
	}
	else
	{
		area = -99;
	}
	return area;
}